//
//  GenericQWSession.m
//  WJAppContext-example
//
//  Created by Yunhai.Wu on 15/11/2.
//  Copyright (c) 2015年 WJ. All rights reserved.
//

#import "QWSession.h"
#import "UICKeyChainStore.h"
#import "QWStringUtils.h"
#import "BaseQWObject.h"
#import "QWAppContextConfig.h"

NSString * const UserLoginedNotification = @"UserLoginedNotification";

NSString * const UserLogoutNotification = @"UserLogoutNotification";

#define KEYCHAIN_STORE_TOKEN_KEY @"appTokenKey"

@interface QWSession ()
@property (nonatomic, copy) id<IQWToken> token;
@property (nonatomic, strong) NSLock *refLock;
@property (nonatomic, strong) UICKeyChainStore *refKeyChainStore;
@property (nonatomic) Class tokenClazz;
@end

@implementation QWSession

DEF_SINGLETON_INIT(QWSession)

-(void) deleteStorage {
    [_refKeyChainStore removeItemForKey:KEYCHAIN_STORE_TOKEN_KEY];
}

-(void) syncStorage {
    if (_token) {
        NSData *tokenData = [QWJSON toJson:_token];
        [_refKeyChainStore setData:tokenData forKey:KEYCHAIN_STORE_TOKEN_KEY];
    }
}

-(void) loadStorage {
    if ([_refKeyChainStore contains:KEYCHAIN_STORE_TOKEN_KEY]) {
        NSData *tokenData = [_refKeyChainStore dataForKey:KEYCHAIN_STORE_TOKEN_KEY];
        if (tokenData) {
            self.token = [QWJSON fromJsonData:tokenData type:_tokenClazz];
        }
    }
}

/**
 *  初始化方法
 */
-(void) singleInit {
    self.refKeyChainStore = [[UICKeyChainStore alloc] initWithService:[[QWAppContextConfig sharedInstance] keychainDefaultService] accessGroup:[[QWAppContextConfig sharedInstance] keychainAccessGroup]];
    Class clazz = [[QWAppContextConfig sharedInstance] tokenClass];
    if (clazz != Nil) {
        self.tokenClazz = clazz;
    } else {
        NSString *reason = [NSString stringWithFormat:@"需要在QWAppContextConfig中配置TokenClass"];
        @throw [NSException exceptionWithName:@"QWSessionException" reason:reason userInfo:nil];
        return;
    }
    self.refLock = [[NSLock alloc] init];
    [self loadStorage];
}


#pragma mark IQWSession
-(id<IQWToken>) getToken {
    if ([self isLogined]) {
        return _token;
    }
    return nil;
}

-(void) logined:(id<IQWToken>) token {
    [_refLock lock];
    if (token) {
        self.token = token;
        [self syncStorage];
        [[NSNotificationCenter defaultCenter] postNotificationName:UserLoginedNotification object:self];
    }
    [_refLock unlock];
}

-(void) logout {
    [_refLock lock];
    if (_token) {
        self.token = nil;
        [self deleteStorage];
        [[NSNotificationCenter defaultCenter] postNotificationName:UserLogoutNotification object:self];
    }
    [_refLock unlock];
}

-(BOOL) isLogined {
    if (_token == nil)
        return NO;
    if ([_token invalidTime] > 0 && [_token invalidTime] < [[NSDate date] timeIntervalSince1970]) {
        [self logout];
        return NO;
    }
    
    return YES;
}

@end
